package com.jy.modules.cims.component.plan;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.sysUtils.CollectionsUtils;
import com.jy.modules.cims.common.sysUtils.DateTimeUtils;
import com.jy.modules.cims.common.sysUtils.SearchParamUtil;
import com.jy.modules.cims.common.sysUtils.SimpleStringUtils;
import com.jy.modules.cims.component.api.IJieYueSend;
import com.jy.modules.cims.component.common.service.TCMmCreditDetailService;
import com.jy.modules.cims.component.credit.credit.ICreditFee;
import com.jy.modules.cims.component.creditRight.plan.CreditPlanConstant;
import com.jy.modules.cims.data.common.dao.TCMmCreditSettleParamDao;
import com.jy.modules.cims.data.common.dao.TCMmDefaultParamDao;
import com.jy.modules.cims.data.common.dao.TCMmRefundPlanDao;
import com.jy.modules.cims.data.common.dto.TCMmCostPlanDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditSettleParamDTO;
import com.jy.modules.cims.data.common.dto.TCMmDefaultParamDTO;
import com.jy.modules.cims.data.common.dto.TCMmRefundPlanDTO;
import com.jy.modules.cims.data.dao.CostPlanDao;
import com.jy.modules.cims.data.dao.RepaymentPlanDao;
import com.jy.modules.cims.data.dto.CreditDetailDto;
import com.jy.modules.cims.data.dto.credit.BatchCreditQueryDto;
import com.jy.modules.cims.data.dto.credit.BatchCreditQueryResultDto;
import com.jy.modules.cims.data.dto.credit.BatchCreditTranferListDTO;
import com.jy.modules.cims.data.dto.credit.CreditFeeDto;
import com.jy.modules.cims.data.dto.credit.CreditFeeParamDto;
import com.jy.modules.cims.data.dto.credit.CreditRepayPlanQueryDto;
import com.jy.modules.cims.data.dto.credit.CreditRepayPlanQueryResultDto;
import com.jy.modules.cims.data.interact.api.JieYueResponseData;
import com.jy.modules.cims.data.interact.api.request.RequestRefundPlanSearchDTO;
import com.jy.modules.cims.data.interact.api.response.ResponseRefundPlanSearchDTO;
import com.jy.modules.cims.data.interact.api.response.ResponseRefundPlanSearchPlanDTO;
import com.jy.modules.cims.data.interact.core.credit.response.ResponseRepayPlanDTO;
import com.jy.modules.cims.interact.ICInteract;
import com.jy.modules.platform.sysconfig.service.SysConfigService;

/**
 * @description 实现生成还款计划和结算计划，以及变更还款计划和结算计划<br>
 *              <p>
 *              1.<code>doCreatPlan</code>： 实现生成还款计划和结算计划，
 *              已经确认的债权，如果系统没有生成还款计划的，需要重新生成还款计划；如果系统没有生成结算计划的，需要重新生成结算计划。<br>
 *              调用核心接口，根据合同号获取还款计划，保存入库，结算计划根据还款计划、债权月还、合约参数生成。
 *              </p>
 *              <p>
 *              2.<code>doChangePlan</code>： 变更还款计划和计算计划，<br>
 *              对于提前结清(核心债权状态 88-债权重组; 89-展期结清;
 *              90-还款日变更)，未作过变更的，需要对还款计划和结算计划做变更处理。
 *              根据债权明细的结清日期，如果结清日期为空，从调接口获取结清日期，如果接口返回的结清日期为空，结清日期为当前日期的前一天。
 *              根据结清日期取最近一期时间的结算计划，变更。
 *              </p>
 * @author shengzhoutao
 * @date 2016-04-18
 */
@Service("com.jy.modules.cims.component.plan.CPlanImpl")
public class CPlanImpl implements ICPlan {
	
	@Autowired
	private TCMmDefaultParamDao tCMmDefaultParamDao;

	@Autowired
	private TCMmCreditSettleParamDao creditSettleParamDao;

	@Autowired
	private TCMmRefundPlanDao tCMmRefundPlanDao;

	@Autowired
	private CostPlanDao costPlanDao;

	@Autowired
	private RepaymentPlanDao repaymentPlanDao;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.credit.credit.CreditFeeImpl")
	private ICreditFee creditFeeImpl;

	@Autowired
	@Qualifier("com.jy.modules.cims.interact.CCInteractImpl")
	private ICInteract iCInteract;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCreditDetailService")
	private TCMmCreditDetailService service;

	@Autowired
	@Qualifier("com.jy.modules.platform.sysconfig.service.SysConfigService")
	private SysConfigService sysConfigService;

	@Autowired
	@Qualifier("jieYueSendService")
	private IJieYueSend jieYueSend;

	/**
	 * @Description 生成还款计划和结算计划
	 * @param creditDetailDto
	 *            参数，债权明细对象。
	 *            可以调用:creditRightDao.searchCreditDetailForCreatPlan(...)
	 *            查询出来债权明细的必须字段属性。
	 * @throws Exception
	 */
	public void doCreatPlan(CreditDetailDto creditDetailDto) throws Exception {
		String creditCode = creditDetailDto.getCreditCode(); // 债权编号
		String transferId = creditDetailDto.getTransferId(); // 转让编号
		String creditSource = creditDetailDto.getCreditSource(); // 债权来源
		int refundPlanRows = creditDetailDto.getRefundPlanRows();// 还款计划条数
		int costPlanRows = creditDetailDto.getCostPlanRows();// 结算计划条数

		if ((refundPlanRows > 0 && costPlanRows > 0)) {
			return;
		}

		// 调用核心接口，根据合同号获取还款计划。
		CreditRepayPlanQueryDto creditRepayPlanQueryDto = new CreditRepayPlanQueryDto();
		creditRepayPlanQueryDto.setContractNo(creditCode);
		CreditRepayPlanQueryResultDto creditRepayPlanQueryResultDto = iCInteract.getCreditRepayPlan(creditRepayPlanQueryDto);
		if (creditRepayPlanQueryResultDto == null) {
			throw new Exception(java.text.MessageFormat.format("调用核心接口，根据合同号【{0}】获取还款计划返回为空", new Object[] { creditCode }));
		}

		List<ResponseRepayPlanDTO> planDataList = creditRepayPlanQueryResultDto.getPlantDataList();// 还款计划

		// 生成还款计划,生成结算计划begin..........................................
		// 生成还款计划
		creatRefundPlan(creditDetailDto, planDataList);

		// 生成结算计划
		creatCostPlan(creditDetailDto, planDataList);
		// 生成还款计划,生成结算计划end............................................

		// 更新债权明细最新账单日
		if (CimsConstant.CREDIT_SOURCE_LOA.equals(creditSource)) {

			service.updateTCMmCreditDetailBillDate(transferId, creditRepayPlanQueryResultDto.getBillDate());
		}

	}

	/**
	 * @Description 变更还款计划和结算计划
	 * @param creditDetailDto
	 *            债权明细
	 * @throws Exception
	 */
	public void doChangePlan(CreditDetailDto creditDetailDto) throws Exception {
		String coreCreditStatus = creditDetailDto.getCoreCreditStatus();// 核心债权状态
		String changeType = getChangeType(coreCreditStatus);// 变更类型
		creditDetailDto.setPlanStatus(changeType);

		// 正常结清/贷款转出 正常贷款/贷款回购/已转让在途/ 已转让在途/已确认转让/已赎回，不需要处理变更还款计划和结算计划流程
		if (!SimpleStringUtils.hasText(changeType)) {
			return;
		}

		if (creditDetailDto.getBizDate() == null) {
			creditDetailDto = setBizDate(creditDetailDto);
		}

		// 获取结算计划期数
		creditDetailDto
				.setSettleDate((creditDetailDto.getBizDate() != null) ? (creditDetailDto.getBizDate()) : DateTimeUtils.addDays(new Date(), -1));
		int currentTime = getChangePlanCurrentTime(creditDetailDto);
		if (currentTime <= 0) {
			throw new Exception(java.text.MessageFormat.format(
					"获取债权编号【{0}】，转让编号【{1}】，变更日期【{2}】的结算计划期数出错！",
					new Object[] { creditDetailDto.getCreditCode(), creditDetailDto.getTransferId(),
							DateTimeUtils.formatDate(creditDetailDto.getSettleDate(), "yyyy-MM-dd") }));
		}

		creditDetailDto.setCurrentTime(new Long(currentTime));

		// ////////////////////////////////////////////////////////////////////////
		// 处理提前结清(核心债权状态 88-债权重组; 89-展期结清; 90-还款日变更)
		boolean doAdcanceFinish = true;
		if (CimsConstant.CORE_CREDIT_STATUS_SETTLE_AHEAD.equals(coreCreditStatus)) {
			// 查询对象违约信息
			TCMmDefaultParamDTO defaultParam = getDefaultParam(creditDetailDto);
			if (null != defaultParam) {
				// 虚拟现金流
				if (CreditPlanConstant.DEAL_MODE_VIRUALCASH.equals(defaultParam.getDisposeType())) {
					doAdcanceFinish = false;
				}
			}
		}

		if (doAdcanceFinish == false) {// 处理虚拟现金流
			dealPlanForVirtual(creditDetailDto);
		} else { // 处理提前结清
			dealPlanForAdcanceFinish(creditDetailDto);
		}
		// ////////////////////////////////////////////////////////////////////////
	}

	// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
	// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * @Description 生成还款计划 T_C_MM_REFUND_PLAN
	 * @param creditDetailDto
	 *            债权明细
	 * @param planDataList
	 *            还款计划
	 */
	private void creatRefundPlan(CreditDetailDto creditDetailDto, List<ResponseRepayPlanDTO> planDataList) throws Exception {
		int refundPlanRows = creditDetailDto.getRefundPlanRows();// 还款计划条数
		if (refundPlanRows > 0) {
			return;
		}

		int creditRows = creditDetailDto.getCreditRows();//
		if (creditRows > 0) {// 如果受让债权再进行债权转让
			TCMmRefundPlanDTO tCMmRefundPlanDTO = new TCMmRefundPlanDTO();
			tCMmRefundPlanDTO.setCreditorCode(creditDetailDto.getCreditCode());
			tCMmRefundPlanDTO.setTransferId(creditDetailDto.getTransferId());
			costPlanDao.copyRefundPlan(SearchParamUtil.getSearchParam(tCMmRefundPlanDTO));
			return;
		}

		if (CollectionsUtils.isEmpty(planDataList)) {
			throw new Exception(java.text.MessageFormat.format("调用核心接口，根据合同号【{0}】获取还款计划返回为空", new Object[] { creditDetailDto.getCreditCode() }));
		}
		planDataList = setRepayPlanList(planDataList, creditDetailDto);

		// 批量新增还款计划
		if (CimsConstant.PRODUCT_TYPE_CREDIT.equals(creditDetailDto.getProductType())) {
			repaymentPlanDao.insertPlanList(planDataList);
		} else {
			repaymentPlanDao.insertPlanListDYD(planDataList);
		}
	}

	/**
	 * @Description 生成结算计划 T_C_MM_COST_PLAN
	 * @param creditDetailDto
	 *            债权明细
	 * @param planDataList
	 *            还款计划
	 * @throws Exception
	 */
	private void creatCostPlan(CreditDetailDto creditDetailDto, List<ResponseRepayPlanDTO> planDataList) throws Exception {
		int costPlanRows = creditDetailDto.getCostPlanRows();// 结算计划条数
		if (costPlanRows > 0) {
			return;
		}

		// 获取债权结算参数
		TCMmCreditSettleParamDTO creditSettleParamDTO = getCreditSettleParam(creditDetailDto);
		String settleType = creditSettleParamDTO.getSettleType() == null ? "" : creditSettleParamDTO.getSettleType();
		List<TCMmCostPlanDTO> costPlanList = new ArrayList<TCMmCostPlanDTO>();

		String value = sysConfigService.queryValueByCode("PROCESS_DIFFERENT_RATE_PLAN_COOPERORGCODE");

		boolean differentRate = false;
		if(SimpleStringUtils.hasText(value)){
			differentRate = isDifferentRepayPlan(value, creditDetailDto.getContractCode());
		}
		
		if ("01".equals(settleType) && CollectionsUtils.isNotEmpty(planDataList) && !differentRate) {// 借款人结算方式
			costPlanList = getCostPlanListForBorrower(planDataList, creditDetailDto, creditSettleParamDTO);
		} else if(differentRate) {
			costPlanList = getCostPlanListForDifferentRate(creditDetailDto, creditSettleParamDTO);
		} else {
			costPlanList = getCostPlanListForGeneral(creditDetailDto, creditSettleParamDTO);
		}


		if (CollectionsUtils.isEmpty(costPlanList)) {
			return;
		}
		
		if (CollectionsUtils.isNotEmpty(costPlanList)) {
			// 批量新增结算计划
			costPlanDao.insertCostPlan(costPlanList);
		}
	}

	/**
	 * @Description 处理提前结清
	 * @param creditDetailDto
	 *            债权明细
	 */
	private void dealPlanForAdcanceFinish(CreditDetailDto creditDetailDto) {
		CreditFeeParamDto creditFeeParamDto = new CreditFeeParamDto();
		creditFeeParamDto.setTransferId(creditDetailDto.getTransferId());// 债权转让编号
		creditFeeParamDto.setContractCode(creditDetailDto.getContractCode());// 合约编号
		creditFeeParamDto.setCurrentTime(creditDetailDto.getCurrentTime());// 当前期次
		creditFeeParamDto.setSettleStatus(CreditPlanConstant.DEAL_MODE_ADVANCEFINISH);// 处理方式:01-提前结清
		CreditFeeDto creditFeeDto = creditFeeImpl.getAbnormalSettleInfo(creditFeeParamDto);

		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("creditCode", creditDetailDto.getCreditCode());// 债权编号
		paramMap.put("transferId", creditDetailDto.getTransferId());// 债权转让编号
		paramMap.put("currentTime", creditDetailDto.getCurrentTime());// 当前期次
		// 更新剩余期数还款计划：应还本、应还息、月还的金额都为0
		repaymentPlanDao.updateAdvanceRepaymentPlans(paramMap);// 更新贷款计划
		// 更新剩余期数结算计划：已结算，自动月还不再处理
		repaymentPlanDao.updateCostPlans(paramMap);

		// 更新当前一期的还款计划：还款状态，更新一条数据
		paramMap.put("planStatus", creditDetailDto.getPlanStatus());// 还款状态
		repaymentPlanDao.updatePlanChanged(paramMap);

		paramMap.put("creditStatus", creditDetailDto.getPlanStatus());// 还款状态
		paramMap.put("mustAmount", creditFeeDto.getMustAmount());// 应还本
		paramMap.put("matchAmount", creditFeeDto.getMatchAmount());// 实际匹配金额
		paramMap.put("returnAmount", creditFeeDto.getReturnAmount());// 返回金额
		// 更新当前一期结算计划：还款状态、实际匹配金额、返回金额，更新一条数据
		repaymentPlanDao.updateCostChanged(paramMap);
	}

	/**
	 * @Description 处理虚拟现金流
	 * @param creditDetailDto
	 *            债权明细
	 */
	private void dealPlanForVirtual(CreditDetailDto creditDetailDto) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("creditCode", creditDetailDto.getCreditCode());// 债权编号
		paramMap.put("transferId", creditDetailDto.getTransferId());// 债权转让编号
		paramMap.put("currentTime", creditDetailDto.getCurrentTime());// 当前期次
		repaymentPlanDao.updateVirtualRepaymentPlans(paramMap);// 更新虚拟现金流还款计划

		paramMap.put("planStatus", creditDetailDto.getPlanStatus());// 还款状态
		repaymentPlanDao.updatePlanChanged(paramMap);// 更新该期还款计划的状态，更新一条数据

		// paramMap.put("creditStatus", creditDetailDto.getPlanStatus());// 还款状态
		// repaymentPlanDao.updateCostPlanChanged(paramMap);// 更新当前一期结算计划：还款状态
		// ,更新一条数据
	}

	/**
	 * @Description 查询对象违约信息
	 * @param creditDetailDto
	 *            债权明细
	 * @return TCMmDefaultParamDTO 违约信息
	 */
	private TCMmDefaultParamDTO getDefaultParam(CreditDetailDto creditDetailDto) {
		TCMmDefaultParamDTO defaultParam = new TCMmDefaultParamDTO();
		defaultParam.setContractCode(creditDetailDto.getContractCode());// 合约编号
		defaultParam.setType(creditDetailDto.getPlanStatus());// 违约类型，异常结算类型

		List<TCMmDefaultParamDTO> defaultParamList = tCMmDefaultParamDao.searchTCMmDefaultParam(SearchParamUtil.getSearchParam(defaultParam));
		if (CollectionsUtils.isNotEmpty(defaultParamList)) {
			return defaultParamList.get(0);
		}

		return null;
	}

	/**
	 * @Description 获取结算参数，如果多条结算参数，取月还方式对应的结算参数。
	 * @param creditDetailDto
	 *            债权明细
	 * @return TCMmCreditSettleParamDTO 结算参数
	 */
	private TCMmCreditSettleParamDTO getCreditSettleParam(CreditDetailDto creditDetailDto) {
		TCMmCreditSettleParamDTO creditSettleParamDTO = new TCMmCreditSettleParamDTO();
		creditSettleParamDTO.setContractCode(creditDetailDto.getContractCode());// 合约编号
		List<TCMmCreditSettleParamDTO> creditSettleParamList = creditSettleParamDao.searchTCMmCreditSettleParam(SearchParamUtil
				.getSearchParam(creditSettleParamDTO));
		creditSettleParamDTO = creditSettleParamList.get(0);

		// 月还还款方式： 默认取债权明细的 月还还款方式, 如果月还还款方式 为空，取结算参数的 月还还款方式
		if (SimpleStringUtils.hasText(creditDetailDto.getRepayType())) {
			for (TCMmCreditSettleParamDTO creditSettleParam : creditSettleParamList) {
				// 如果配置多条参数，取 月还还款方式 匹配对应的参数
				if (creditDetailDto.getRepayType().equals(creditSettleParam.getRepayType())) {
					creditSettleParamDTO = creditSettleParam;
					return creditSettleParamDTO;
				}
			}
		}

		return creditSettleParamDTO;
	}

	/**
	 * @Description 获取结算计划期数
	 * @param creditDetailDto
	 *            债权明细
	 * @return currentTime 结算计划期数
	 */
	private int getChangePlanCurrentTime(CreditDetailDto creditDetailDto) {
		int currentTime = 0;

		TCMmCostPlanDTO costPlan = new TCMmCostPlanDTO();
		costPlan.setTransferId(creditDetailDto.getTransferId());// 债权转让编号
		costPlan.setCreditorCode(creditDetailDto.getCreditCode());// 债权编号
		costPlan.setStartDate(creditDetailDto.getSettleDate());// 结算日期

		List<TCMmCostPlanDTO> costPlanList = costPlanDao.searchSurplusCostPlan(SearchParamUtil.getSearchParam(costPlan));
		if (CollectionsUtils.isEmpty(costPlanList)) {
			return currentTime;
		}

		String currentDate = DateTimeUtils.formatDate(new Date(), DateTimeUtils.DEFAULT_DATE_FORMAT);
		for (TCMmCostPlanDTO plan : costPlanList) {
			String startDate = DateTimeUtils.formatDate(plan.getStartDate(), DateTimeUtils.DEFAULT_DATE_FORMAT);
			if (Long.parseLong(startDate) >= Long.parseLong(currentDate)) {
				String planStatus = plan.getPlanStatus() == null ? "" : plan.getPlanStatus();
				currentTime = plan.getCurrentTime().intValue();
				if (CimsConstant.CREDIT_SETTLE_STATUS.equals(planStatus)) {// 已经结算的期
					currentTime = currentTime + 1;
				}

				return currentTime;
			}
		}

		return currentTime;
	}

	/**
	 * @Description 填充结算计划
	 * @param creditDetailDto
	 *            债权明细
	 * @param creditSettleParamDTO
	 *            结算参数
	 * @return costPlanList 新的结算计划
	 * @throws Exception
	 */
	private List<TCMmCostPlanDTO> getCostPlanListForGeneral(CreditDetailDto creditDetailDto, TCMmCreditSettleParamDTO creditSettleParamDTO)
			throws Exception {
		TCMmRefundPlanDTO refundPlanDTO = new TCMmRefundPlanDTO();
		refundPlanDTO.setTransferId(creditDetailDto.getTransferId());
		refundPlanDTO.setCreditorCode(creditDetailDto.getCreditCode());
		List<TCMmRefundPlanDTO> refundPlanList = tCMmRefundPlanDao.searchTCMmRefundPlan(SearchParamUtil.getSearchParam(refundPlanDTO));
		if (CollectionsUtils.isEmpty(refundPlanList)) {
			throw new Exception(java.text.MessageFormat.format("生成债权编号【{0}】，转让编号【{1}】，变更日期【{2}】的还款计划失败！",
					new Object[] { creditDetailDto.getCreditCode(), creditDetailDto.getTransferId(), }));
		}

		List<TCMmCostPlanDTO> costPlanList = new ArrayList<TCMmCostPlanDTO>();
		TCMmCreditSettleParamDTO tCMmCreditSettleParamDTO = null;
		TCMmCostPlanDTO costPlanDTO = null;
		int refundPlanListSize = refundPlanList.size();
		int creditRows = creditDetailDto.getCreditRows();//
		for (int index = 0; index < refundPlanListSize; index++) {
			refundPlanDTO = refundPlanList.get(index);
			tCMmCreditSettleParamDTO = new TCMmCreditSettleParamDTO();
			tCMmCreditSettleParamDTO.setReplaceType(creditSettleParamDTO.getReplaceType());
			TCMmCostPlanDTO tCMmCostPlanDTO = new TCMmCostPlanDTO();
			BigDecimal mustAmount = refundPlanDTO.getMustAmount();
			BigDecimal mustAccrual = refundPlanDTO.getMustAccrual();
			if (creditRows > 0) {// 如果受让债权再进行债权转让
				mustAmount = mustAmount.multiply(creditDetailDto.getThisRepaySum()).divide(refundPlanDTO.getThisRepaySum(), 4);// 应还本
				mustAccrual = mustAccrual.multiply(creditDetailDto.getThisRepaySum()).divide(refundPlanDTO.getThisRepaySum(), 4);// 应还息
			}

			tCMmCostPlanDTO.setMustAmount(mustAmount);// 应还本
			tCMmCostPlanDTO.setMustAccrual(mustAccrual);// 应还息
			CreditFeeDto creditFeeDto = creditFeeImpl.getSettleInfo(tCMmCreditSettleParamDTO, tCMmCostPlanDTO);

			costPlanDTO = new TCMmCostPlanDTO();
			costPlanDTO.setCreditorCode(creditDetailDto.getCreditCode());// 债权编号
			costPlanDTO.setTransferId(creditDetailDto.getTransferId());// 转让编号
			costPlanDTO.setStartDate(refundPlanDTO.getStartDate());// 当期还款起日
			costPlanDTO.setCurrentTime(Long.parseLong(String.valueOf(index + 1)));// 当前期次
			costPlanDTO.setMustAmount(mustAmount);// 应还本
			costPlanDTO.setMustAccrual(mustAccrual);// 应还息
			costPlanDTO.setThisRepaySum(mustAmount.add(mustAccrual));// 月还金额
			costPlanDTO.setMatchAmount(creditFeeDto.getMatchAmount());// 实际匹配金额
			costPlanDTO.setReturnAmount(creditFeeDto.getReturnAmount());// 返回金额

			costPlanList.add(costPlanDTO);
		}

		refundPlanDTO = null;

		return costPlanList;
	}

	/**
	 * @Description 填充结算计划
	 * @param creditDetailDto
	 *            债权明细
	 * @param creditSettleParamDTO
	 *            结算参数
	 * @return costPlanList 新的结算计划
	 * @throws Exception
	 */
	private List<TCMmCostPlanDTO> getCostPlanListForDifferentRate(CreditDetailDto creditDetailDto, TCMmCreditSettleParamDTO creditSettleParamDTO)
			throws Exception {

		RequestRefundPlanSearchDTO request = new RequestRefundPlanSearchDTO();
		JieYueResponseData jieYueResponseData = null;
		if (CimsConstant.CREDIT_SOURCE_LOA.equals(creditDetailDto.getCreditSource())) {
			request.setLoanNumber(creditDetailDto.getCreditCode());
			jieYueResponseData = jieYueSend.searchLoanRefundplan(creditDetailDto.getCooperorgCode(), request);
		}else if(CimsConstant.CREDIT_SOURCE_CRE.equals(creditDetailDto.getCreditSource())){
			request.setLoanNumber(creditDetailDto.getTransferId());
			jieYueResponseData = jieYueSend.searchCreditRefundplan(creditDetailDto.getCooperorgCode(), request);
		}
		
		
		if(null == jieYueResponseData){
			return null;
		}
		
		if(null == jieYueResponseData.getData()){
			return null;
		}
		
		ResponseRefundPlanSearchDTO responseRefundPlan = (ResponseRefundPlanSearchDTO) jieYueResponseData.getData();
		
		List<ResponseRefundPlanSearchPlanDTO> refundPlanList = responseRefundPlan.getPlanList();
		if (CollectionsUtils.isEmpty(refundPlanList)) {
			return null;
		}

		List<TCMmCostPlanDTO> costPlanList = new ArrayList<TCMmCostPlanDTO>();
		TCMmCreditSettleParamDTO tCMmCreditSettleParamDTO = null;
		TCMmCostPlanDTO costPlanDTO = null;
		int refundPlanListSize = refundPlanList.size();
		
		for (int index = 0; index < refundPlanListSize; index++) {
			ResponseRefundPlanSearchPlanDTO refundPlanDTO = refundPlanList.get(index);
			tCMmCreditSettleParamDTO = new TCMmCreditSettleParamDTO();
			tCMmCreditSettleParamDTO.setReplaceType(creditSettleParamDTO.getReplaceType());
			TCMmCostPlanDTO tCMmCostPlanDTO = new TCMmCostPlanDTO();
			BigDecimal mustAmount = refundPlanDTO.getMustAmount();
			BigDecimal mustAccrual = refundPlanDTO.getMustAccrual();

			tCMmCostPlanDTO.setMustAmount(mustAmount);// 应还本
			tCMmCostPlanDTO.setMustAccrual(mustAccrual);// 应还息
			CreditFeeDto creditFeeDto = creditFeeImpl.getSettleInfo(tCMmCreditSettleParamDTO, tCMmCostPlanDTO);

			costPlanDTO = new TCMmCostPlanDTO();
			costPlanDTO.setCreditorCode(creditDetailDto.getCreditCode());// 债权编号
			costPlanDTO.setTransferId(creditDetailDto.getTransferId());// 转让编号
			costPlanDTO.setStartDate(DateTimeUtils.parse(refundPlanDTO.getPaymentDate(), DateTimeUtils.DEFAULT_DATE_FORMAT_2));// 当期还款起日
			costPlanDTO.setCurrentTime(refundPlanDTO.getLoanTerms());// 当前期次
			costPlanDTO.setMustAmount(mustAmount);// 应还本
			costPlanDTO.setMustAccrual(mustAccrual);// 应还息
			costPlanDTO.setThisRepaySum(mustAmount.add(mustAccrual));// 月还金额
			costPlanDTO.setMatchAmount(creditFeeDto.getMatchAmount());// 实际匹配金额
			costPlanDTO.setReturnAmount(creditFeeDto.getReturnAmount());// 返回金额

			costPlanList.add(costPlanDTO);
		}

		return costPlanList;
	}

	/**
	 * @Description 填充结算计划 借款人结算方式
	 * @param plansList
	 *            还款计划
	 * @param creditDetailDto
	 *            债权明细
	 * @param creditSettleParamDTO
	 *            结算参数
	 * @return costPlanList 新的结算计划
	 */
	List<TCMmCostPlanDTO> getCostPlanListForBorrower(List<ResponseRepayPlanDTO> plansList, CreditDetailDto creditDetailDto,
			TCMmCreditSettleParamDTO creditSettleParamDTO) {
		List<TCMmCostPlanDTO> costPlanList = new ArrayList<TCMmCostPlanDTO>();
		TCMmCreditSettleParamDTO tCMmCreditSettleParamDTO = null;
		TCMmCostPlanDTO costPlanDTO = null;

		String coreCreditStatus = creditDetailDto.getCoreCreditStatus();// 核心债权状态
		String changeType = getChangeType(coreCreditStatus);// 变更类型

		for (int index = 0; index < plansList.size(); index++) {
			ResponseRepayPlanDTO plan = plansList.get(index);
			BigDecimal mustAmount = plan.getCurRepayBase();// 应还本
			BigDecimal mustAccrual = plan.getCurRepayInst();// 应还息
			if (SimpleStringUtils.hasText(changeType) && (null == plan.getCurRepayMoney() || plan.getCurRepayMoney().compareTo(BigDecimal.ZERO) == 0)) {
				mustAmount = plan.getCurRepayBase();// 应还本
				mustAccrual = plan.getCurRepayInst();// 应还息
			} else {
				mustAmount = plan.getCurRepayBase().multiply(creditDetailDto.getThisRepaySum()).divide(plan.getCurRepayMoney(), 4);// 应还本
				mustAccrual = plan.getCurRepayInst().multiply(creditDetailDto.getThisRepaySum()).divide(plan.getCurRepayMoney(), 4);// 应还息
			}

			tCMmCreditSettleParamDTO = new TCMmCreditSettleParamDTO();
			tCMmCreditSettleParamDTO.setReplaceType(creditSettleParamDTO.getReplaceType());
			TCMmCostPlanDTO tCMmCostPlanDTO = new TCMmCostPlanDTO();
			tCMmCostPlanDTO.setMustAmount(mustAmount);// 应还本
			tCMmCostPlanDTO.setMustAccrual(mustAccrual);// 应还息
			CreditFeeDto creditFeeDto = creditFeeImpl.getSettleInfo(tCMmCreditSettleParamDTO, tCMmCostPlanDTO);

			costPlanDTO = new TCMmCostPlanDTO();
			costPlanDTO.setCreditorCode(creditDetailDto.getCreditCode());// 债权编号
			costPlanDTO.setTransferId(creditDetailDto.getTransferId());// 转让编号
			costPlanDTO.setCurrentTime(Long.parseLong(String.valueOf(index + 1)));// 当前期次
			costPlanDTO.setStartDate(DateTimeUtils.parse(plan.getCurRepayDate(), "yyyy-MM-dd"));// 当期还款起日
			costPlanDTO.setMustAmount(mustAmount);// 应还本
			costPlanDTO.setMustAccrual(mustAccrual);// 应还息
			costPlanDTO.setThisRepaySum(mustAmount.add(mustAccrual));// 月还金额
			costPlanDTO.setMatchAmount(creditFeeDto.getMatchAmount());// 实际匹配金额
			costPlanDTO.setReturnAmount(creditFeeDto.getReturnAmount());// 返回金额

			costPlanList.add(costPlanDTO);
		}

		return costPlanList;
	}

	/**
	 * 
	 * @param creditDetailDto
	 * @return
	 */
	private CreditDetailDto setBizDate(CreditDetailDto creditDetailDto) {
		CreditDetailDto newCreditDetailDto = creditDetailDto;
		BatchCreditQueryDto batchCreditQueryDto = new BatchCreditQueryDto();
		List<BatchCreditTranferListDTO> batchCreditTranferList = new ArrayList<BatchCreditTranferListDTO>();

		BatchCreditTranferListDTO creditTranferList = new BatchCreditTranferListDTO();
		creditTranferList.setType(creditDetailDto.getCreditSource());
		creditTranferList.setTransferId(creditDetailDto.getTransferId());
		batchCreditTranferList.add(creditTranferList);

		batchCreditQueryDto.setList(batchCreditTranferList);
		BatchCreditQueryResultDto batchCreditQueryResultDto = iCInteract.getCreditDetail(batchCreditQueryDto);
		if (null == batchCreditQueryResultDto) {
			return newCreditDetailDto;
		}

		List<CreditDetailDto> creditList = null;
		if (CimsConstant.CREDIT_SOURCE_CRE.equals(creditDetailDto.getCreditSource())) {
			creditList = batchCreditQueryResultDto.getTransferList();
		} else if (CimsConstant.CREDIT_SOURCE_LOA.equals(creditDetailDto.getCreditSource())) {
			creditList = batchCreditQueryResultDto.getCreditList();

		}
		if (CollectionsUtils.isNotEmpty(creditList)) {
			newCreditDetailDto.setBizDate(creditList.get(0).getBizDate());
			newCreditDetailDto.setCoreCreditStatus(creditList.get(0).getCoreState());
		}

		return newCreditDetailDto;
	}

	/**
	 * @Description 填充还款计划列表，赋值转让编号、债权编号、月还金额
	 * @param planDataList
	 *            还款计划列表
	 * @param creditDetailDto
	 *            债权明细
	 * @return 新的还款计划列表
	 */
	private List<ResponseRepayPlanDTO> setRepayPlanList(List<ResponseRepayPlanDTO> planDataList, CreditDetailDto creditDetailDto) {

		List<ResponseRepayPlanDTO> newList = new ArrayList<ResponseRepayPlanDTO>();
		for (ResponseRepayPlanDTO responseRepayPlanDTO : planDataList) {
			responseRepayPlanDTO.setTransferId(creditDetailDto.getTransferId());
			responseRepayPlanDTO.setCreditCode(creditDetailDto.getCreditCode());
			responseRepayPlanDTO.setCurRepayDate(responseRepayPlanDTO.getCurRepayDate() == null ? DateTimeUtils.formatDate(new Date(),
					DateTimeUtils.DEFAULT_DATE_TIME_FORMAT) : responseRepayPlanDTO.getCurRepayDate());
			responseRepayPlanDTO.setThisRepaySum(creditDetailDto.getThisRepaySum() == null ? BigDecimal.ZERO : creditDetailDto.getThisRepaySum());
			responseRepayPlanDTO.setCurRepayBase(responseRepayPlanDTO.getCurRepayBase() == null ? BigDecimal.ZERO : responseRepayPlanDTO
					.getCurRepayBase());
			responseRepayPlanDTO.setCurRepayInst(responseRepayPlanDTO.getCurRepayInst() == null ? BigDecimal.ZERO : responseRepayPlanDTO
					.getCurRepayInst());
			responseRepayPlanDTO.setRepayPanelty(responseRepayPlanDTO.getRepayPanelty() == null ? BigDecimal.ZERO : responseRepayPlanDTO
					.getRepayPanelty());
			responseRepayPlanDTO.setRepayDefault(responseRepayPlanDTO.getRepayDefault() == null ? BigDecimal.ZERO : responseRepayPlanDTO
					.getRepayDefault());
			newList.add(responseRepayPlanDTO);
		}
		return newList;
	}

	/**
	 * @Description 将核心债权状态转换成变更类型，等同于异常处理类型，正常结清/贷款转出 正常贷款/贷款回购/已转让在途/
	 *              已转让在途/已确认转让/已赎回，不需要处理变更还款计划和结算计划流程
	 * @param loanStatus
	 *            核心债权状态 95-提前结清;96-撤销; 88-债权重组; 89-展期结清; 90-还款日变更
	 * @return 变更类型
	 */
	private String getChangeType(final String coreStatus) {
		Map<String, String> changeTypeMap = new HashMap<String, String>();
		changeTypeMap.put(CimsConstant.CORE_CREDIT_STATUS_SETTLE_AHEAD, CreditPlanConstant.CHANGE_TYPE_ADVANCEFINISH);
		changeTypeMap.put(CimsConstant.CORE_CREDIT_STATUS_SETTLE_CANCEL, CreditPlanConstant.CHANGE_TYPE_CANCEL);
		changeTypeMap.put(CimsConstant.CORE_CREDIT_STATUS_SETTLE_RECOMBINE, CreditPlanConstant.CHANGE_TYPE_ANEW);
		changeTypeMap.put(CimsConstant.CORE_CREDIT_STATUS_SETTLE_EXHIBITION, CreditPlanConstant.CHANGE_TYPE_ROLLFINISH);
		changeTypeMap.put(CimsConstant.CORE_CREDIT_STATUS_SETTLE_CHANGEDATE, CreditPlanConstant.CHANGE_TYPE_CHANGEDATE);

		return changeTypeMap.get(coreStatus);
	}
	
	/**
	 * 判断是否是机构获取结算计划
	 * @author zhangmi
	 * @date  2017年5月8日
	 * @param str
	 * @param cCode
	 * @return
	 */
	private boolean isDifferentRepayPlan(String str,String cCode){
		String [] aryStr = str.split(",");
		for (String string : aryStr) {
			if(string.trim().equals(cCode)){
				System.out.println("Xp");
				return true;
			}
		}
		return false;
	}
}
